import 'dart:ffi';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
// import 'package:kerala_lottery/tools/KaL_Config.dart';

import '../KaL_Config.dart';
import '../request/AL_HttpRequest.dart';
import 'KL_keralaLottoModel.dart';

class KL_keralaLottoDataModel {
  // 单例
  factory KL_keralaLottoDataModel() => _getInstance()!;
  static KL_keralaLottoDataModel get instance => _getInstance()!;
  static KL_keralaLottoDataModel? _instance;
  KL_keralaLottoDataModel._internal();
  static KL_keralaLottoDataModel? _getInstance() {
    _instance ??= KL_keralaLottoDataModel._internal();
    return _instance;
  }

  late var allDatas = []; //全部json数据
  late var allDataModels = []; //全部模型数据

  ///中奖头奖号码
  late var allPrizes_1st_ticketNumbers = []; //全部
  late var mondayPrizes_1st_ticketNumbers = []; //周一
  late var tuesdayPrizes_1st_ticketNumbers = []; //周二
  late var wednesdayPrizes_1st_ticketNumbers = []; //周三
  late var thursdayPrizes_1st_ticketNumbers = []; //周四
  late var fridayPrizes_1st_ticketNumbers = []; //周五
  late var saturdayPrizes_1st_ticketNumbers = []; //周六
  late var sundayPrizes_1st_ticketNumbers = []; //周日

  late var KL_CalculateTitles = []; //
  ///开奖日期
  late var drawDatas = []; //全部开奖日期
  late var mondayDrawDatas = []; //周一开奖日期
  late var tuesdayDrawDatas = []; //周二开奖日期
  late var wednesdayDrawDatas = []; //周三开奖日期
  late var thursdayDrawDatas = []; //周四开奖日期
  late var fridayDrawDatas = []; //周五开奖日期
  late var saturdayDrawDatas = []; //周六开奖日期
  late var sundayDrawDatas = []; //周日开奖日期

  late var KL_AnalyticsRowResults = []; //Analytics每一行开奖结果
  late var KL_CalculatedDrawings = []; //号码中奖次数
  late var KL_AverageSkipping = []; //平均遗漏
  late var KL_MaximumSkipping = []; //最大遗漏→
  late var KL_MaximumConsecution = []; //最大连开→
  late var KL_ChooseNumbers = []; //待选号码

  ///下一期数据模型
  late var nextDrawnModel = NextDrawModel();

  ///checker数据
  late var checkerDatas = [];

  //获取数据
  Future<bool> getAllData() async {
    var response = await ALHttprequest().getAllKeralaLottoData();
    debugPrint('$response');

    int status = response['status'];
    List data = response['data'];
    if (status == 200 && data.isNotEmpty) {
      allDatas = data;
      configAllDataModels(data);
      configWeekDatas(data);
      return true;
    }
    return false;
  }

  //获取下一期
  Future<bool> getNextDrawnData() async {
    var response = await ALHttprequest().getKeralaLotteryNextDranw();
    debugPrint('$response');

    int status = response['status'];
    var data = response['data'];
    if (status == 200 && data.isNotEmpty) {
      nextDrawnModel = NextDrawModel.fromJson(data);
      return true;
    }
    return false;
  }

  ///获取当前期详情
  // Future<bool> getCurrentDrawnDetail(String drawNumber) async {
  //   var response = await ALHttprequest().getCurrentDrawnDetail(drawNumber);
  //   debugPrint('$response');
  //   int status = response['status'];
  //   var data = response['data'];
  //   if (status == 200 && data.isNotEmpty) {
  //     return true;
  //   }
  //   return false;
  // }

  ///获取日期字符串列表
  getweekdayDrawDatas(int weekday) {
    List results = [];
    List calculateTitles = _getCalculateTitle();
    switch (weekday) {
      case 0:
        results = drawDatas;
      case 1:
        results = mondayDrawDatas;
      case 2:
        results = tuesdayDrawDatas;
      case 3:
        results = wednesdayDrawDatas;
      case 4:
        results = thursdayDrawDatas;
      case 5:
        results = fridayDrawDatas;
      case 6:
        results = saturdayDrawDatas;
      case 7:
        results = sundayDrawDatas;
      default:
        return [];
    }
    return results.reversed.toList() + calculateTitles;
    // return results.reversed.toList();
  }

  _getCalculateTitle() {
    var titles = [
      'Drawn\nCount',
      'Average\nSkipping',
      'Maximum\nSkipping',
      'Maximum\nConsecution',
      'Choose &\nSave Ticket',
    ];
    KL_CalculateTitles = titles;
    return titles;
  }

  ///数据转模型数组
  void configAllDataModels(List datas) {
    for (var data in datas) {
      Map prizes = data['prizes'] ?? {};
      if (prizes.isNotEmpty) {
        var model = KL_keralaLottoModel.fromJson(data);
        allDataModels.add(model);
        configCheckerDatas(model);
        configDrawDatas(model);
      }
    }
  }

  ///Analytics中奖号码数组
  void configWeekDatas(List datas) {
    if (datas.isNotEmpty) {
      for (Map element in datas) {
        String draw_datetime_utc = element['draw_datetime_utc'];
        // 2. 转换为 DateTime 对象
        DateTime dateTime =
            DateTime.parse(draw_datetime_utc + '+0000').toLocal();
        // 3. 获取星期几
        int weekday = dateTime.weekday; // 1 = Monday, 7 = Sunday

        Map prizes = element['prizes'] ?? {};
        if (prizes.isNotEmpty) {
          Map firstPrize = prizes['1st'];
          List ticketNumbers = firstPrize['ticket_numbers'];
          if (ticketNumbers.isNotEmpty) {
            String numberStr = ticketNumbers[0];
            // 使用 split 方法将字符串转换为字符串数组
            List<String> charArray = numberStr.split('');
            allPrizes_1st_ticketNumbers.add(charArray);
            switch (weekday) {
              case 1:
                mondayPrizes_1st_ticketNumbers.add(charArray);
                break;
              case 2:
                tuesdayPrizes_1st_ticketNumbers.add(charArray);
                break;
              case 3:
                wednesdayPrizes_1st_ticketNumbers.add(charArray);
                break;
              case 4:
                thursdayPrizes_1st_ticketNumbers.add(charArray);
                break;
              case 5:
                fridayPrizes_1st_ticketNumbers.add(charArray);
                break;
              case 6:
                saturdayPrizes_1st_ticketNumbers.add(charArray);
                break;
              case 7:
                sundayPrizes_1st_ticketNumbers.add(charArray);
                break;
              default:
            }
          }
        }
      }
      KL_getAnalyticsResults(0);
    }
  }

  //匹配Analytics每一行开奖结果
  KL_getAnalyticsResults(int weekday) async {
    KL_AnalyticsRowResults.clear();
    var winningNumbers = [];
    switch (weekday) {
      case 0:
        winningNumbers = allPrizes_1st_ticketNumbers;
      case 1:
        winningNumbers = mondayPrizes_1st_ticketNumbers;
        break;
      case 2:
        winningNumbers = tuesdayPrizes_1st_ticketNumbers;
        break;
      case 3:
        winningNumbers = wednesdayPrizes_1st_ticketNumbers;
        break;
      case 4:
        winningNumbers = thursdayPrizes_1st_ticketNumbers;
        break;
      case 5:
        winningNumbers = fridayPrizes_1st_ticketNumbers;
        break;
      case 6:
        winningNumbers = saturdayPrizes_1st_ticketNumbers;
        break;
      case 7:
        winningNumbers = sundayPrizes_1st_ticketNumbers;
    }

    ///遍历全部开奖结果，每一行
    var winningNumbersList = winningNumbers.reversed.toList();
    for (var i = 0; i < winningNumbersList.length; i++) {
      var results = [];
      List resultNumbers = winningNumbersList[i];

      ///遍历每个号码分区
      for (int k = 0; k < KaL_Config.digitsStringArr.length; k++) {
        List digitLetters = KaL_Config.otherDigitNums;
        var codeArray = [];
        int jStr = i + 1;
        //第一个字母分区
        if (k == 0) {
          digitLetters = KaL_Config.firstDigitLetters;
          for (int j = 0; j < digitLetters.length; j++) {
            Map element = digitLetters[j];
            var code = element['code'];
            var rowCode = {'code': (jStr).toString(), 'isRight': false};
            if (i <= 0) {
              //2个字母
              for (var l = 0; l < 2; l++) {
                var resCode = resultNumbers[l];
                if (code == resCode) {
                  rowCode = {'code': code, 'isRight': true};
                }
              }
            } else {
              ///第二行，开始
              var rowResults = KL_AnalyticsRowResults[i - 1];
              Map rowMap = rowResults[k];
              List rowCodes = rowMap['nums'];
              Map rowCodeMap = rowCodes[j];
              bool isRight = rowCodeMap['isRight']; //上一行对应位置是否中奖号码
              var lastRowCode = rowCodeMap['code'];
              if (isRight) {
                rowCode = {'code': (1).toString(), 'isRight': false};
              } else {
                rowCode = {
                  'code': (int.parse(lastRowCode) + 1).toString(),
                  'isRight': false
                };
              }

              ///查看开奖号码是否在当前分区
              for (var l = 0; l < 2; l++) {
                var resCode = resultNumbers[l];
                if (code == resCode) {
                  rowCode = {'code': code, 'isRight': true};
                }
              }
            }

            codeArray.add(rowCode);
          }
          Map digitMap = {'title': '', 'nums': codeArray};
          results.add(digitMap);
        }

        ///数字号码分区
        else {
          for (int j = 0; j < digitLetters.length; j++) {
            Map element = digitLetters[j];
            var code = element['code'];
            var rowCode = {'code': (jStr).toString(), 'isRight': false};

            if (i <= 0) {
              var resCode = resultNumbers[k + 1];
              if (code == resCode) {
                rowCode = {'code': code, 'isRight': true};
              }
            } else {
              ///第二行，开始
              var rowResults = KL_AnalyticsRowResults[i - 1];
              Map rowMap = rowResults[k];
              List rowCodes = rowMap['nums'];
              Map rowCodeMap = rowCodes[j];
              bool isRight = rowCodeMap['isRight']; //上一行对应位置是否中奖号码
              var lastRowCode = rowCodeMap['code'];
              if (isRight) {
                rowCode = {'code': (1).toString(), 'isRight': false};
              } else {
                rowCode = {
                  'code': (int.parse(lastRowCode) + 1).toString(),
                  'isRight': false
                };
              }

              ///查看开奖号码是否在当前分区
              var resCode = resultNumbers[k + 1];
              if (code == resCode) {
                rowCode = {'code': code, 'isRight': true};
              }
            }
            codeArray.add(rowCode);
          }
          Map digitMap = {'title': '', 'nums': codeArray};
          results.add(digitMap);
        }
      }
      KL_AnalyticsRowResults.add(results);
    }
    debugPrint('KL_AnalyticsRowResults---$KL_AnalyticsRowResults');
    KL_getCalculatedDrawings(weekday);
    KL_AnalyticsRowResults.add(KL_CalculatedDrawings);
    KL_AnalyticsRowResults.add(KL_AverageSkipping);
    KL_AnalyticsRowResults.add(KL_MaximumSkipping);
    KL_AnalyticsRowResults.add(KL_MaximumConsecution);
    KL_AnalyticsRowResults.add(KL_ChooseNumbers);
    return KL_AnalyticsRowResults;
  }

  ///组装checker数据
  void configCheckerDatas(KL_keralaLottoModel model) {
    String drawDate = model.draw_datetime_utc;
    List prizes = model.prizes ?? [];
    if (prizes.isNotEmpty) {
      Map checkerData = {'date': drawDate, 'prizes': prizes};
      checkerDatas.add(checkerData);
    }
    // debugPrint('checkerDatas---$checkerDatas');
  }

  ///组装开奖日期字符串数据
  void configDrawDatas(KL_keralaLottoModel model) {
    String drawCode = model.draw_code;
    //1. 获取 draw_datetime_utc
    String drawDate = model.draw_datetime_utc;
    // 2. 转换为 DateTime 对象
    DateTime dateTime = DateTime.parse(drawDate + '+0000').toLocal();
    //3.
    String dateTimeString = DateFormat('dd/MMM/yyyy').format(dateTime);
    int weekday = dateTime.weekday; // 1 = Monday, 7 = Sunday

    var drawDateStr = '$drawCode\n$dateTimeString';
    drawDatas.add(drawDateStr);

    switch (weekday) {
      case 1:
        mondayDrawDatas.add(drawDateStr);
        break;
      case 2:
        tuesdayDrawDatas.add(drawDateStr);
        break;
      case 3:
        wednesdayDrawDatas.add(drawDateStr);
        break;
      case 4:
        thursdayDrawDatas.add(drawDateStr);
        break;
      case 5:
        fridayDrawDatas.add(drawDateStr);
        break;
      case 6:
        saturdayDrawDatas.add(drawDateStr);
        break;
      case 7:
        sundayDrawDatas.add(drawDateStr);
        break;
    }
    // debugPrint('drawDatas---$drawDatas');
  }

  ///号码开奖次数
  KL_getCalculatedDrawings(int weekday) {
    KL_CalculatedDrawings.clear();

    var winningNumbers = [];
    switch (weekday) {
      case 0:
        winningNumbers = allPrizes_1st_ticketNumbers;
      case 1:
        winningNumbers = mondayPrizes_1st_ticketNumbers;
        break;
      case 2:
        winningNumbers = tuesdayPrizes_1st_ticketNumbers;
        break;
      case 3:
        winningNumbers = wednesdayPrizes_1st_ticketNumbers;
        break;
      case 4:
        winningNumbers = thursdayPrizes_1st_ticketNumbers;
        break;
      case 5:
        winningNumbers = fridayPrizes_1st_ticketNumbers;
        break;
      case 6:
        winningNumbers = saturdayPrizes_1st_ticketNumbers;
        break;
      case 7:
        winningNumbers = sundayPrizes_1st_ticketNumbers;
    }

    ///遍历每个号码分区
    for (int k = 0; k < KaL_Config.digitsStringArr.length; k++) {
      List digitLetters = KaL_Config.otherDigitNums;
      var codeCountArray = [];
      if (k == 0) {
        digitLetters = KaL_Config.firstDigitLetters;

        //遍历每个区的号码
        for (int i = 0; i < digitLetters.length; i++) {
          Map digitLetter = digitLetters[i];
          String codeString = digitLetter['code'];
          debugPrint('check---$codeString');
          int codeCount = 0;

          ///每个号码查找开奖次数
          for (int j = 0; j < winningNumbers.length; j++) {
            for (int l = 0; l < 2; l++) {
              List element = winningNumbers[j];
              String winningNumber = element[l];
              if (winningNumber == codeString) {
                codeCount++;
              }
            }
          }
          debugPrint('check---$codeString,,count---$codeCount');
          Map codeCountMap = {'code': codeCount.toString(), 'isRight': false};
          codeCountArray.add(codeCountMap);
        }
        Map digitMap = {'title': '', 'nums': codeCountArray};
        KL_CalculatedDrawings.add(digitMap);
      } else {
        ///遍历每个区的号码
        for (int i = 0; i < digitLetters.length; i++) {
          //遍历每个区的号码
          Map digitLetter = digitLetters[i];
          String codeString = digitLetter['code'];
          debugPrint('check---$codeString');
          int codeCount = 0;

          ///每个号码查找开奖次数
          for (var j = 0; j < winningNumbers.length; j++) {
            List element = winningNumbers[j];
            String winningNumber = element[k + 1];
            if (winningNumber == codeString) {
              codeCount++;
            }
          }
          debugPrint('check---$codeString,,count---$codeCount');
          Map codeCountMap = {'code': codeCount.toString(), 'isRight': false};
          codeCountArray.add(codeCountMap);
        }

        Map digitMap = {'title': '', 'nums': codeCountArray};
        KL_CalculatedDrawings.add(digitMap);
      }
      debugPrint('KL_CalculatedDrawings---$KL_CalculatedDrawings');
    }
    KL_getAverageSkipping();
    KL_getMaximumSkipping();
    KL_getMaximumConsecution();
    KL_getChoosingNumber();
    // return KL_CalculatedDrawings;
  }

  ///计算平均遗漏
  KL_getAverageSkipping() {
    KL_AverageSkipping.clear();
    for (Map element in KL_CalculatedDrawings) {
      List nums = element['nums'];
      List result = [];
      for (int i = 0; i < nums.length; i++) {
        var count;
        if (i <= 12) {
          count = (69 / 5 - 1).round().toString(); //四舍五入后转string
        } else {
          count = (26 / 1 - 1).round().toString();
        }
        Map codeCountMap = {'code': count.toString(), 'isRight': false};
        result.add(codeCountMap);
      }
      Map digitMap = {'title': '', 'nums': result};
      KL_AverageSkipping.add(digitMap);
    }
    debugPrint('KL_AverageSkipping---$KL_AverageSkipping');
  }

  ///计算最大遗漏
  KL_getMaximumSkipping() {
    KL_MaximumSkipping.clear();

    ///遍历每个号码分区
    for (int k = 0; k < KL_CalculatedDrawings.length; k++) {
      Map element = KL_CalculatedDrawings[k];
      List nums = element['nums'];
      List MaxCountArray = [];
      for (int i = 0; i < nums.length; i++) {
        int maxCount = 0;
        for (var j = 0; j < KL_AnalyticsRowResults.length; j++) {
          List rowResults = KL_AnalyticsRowResults[j];
          Map rowMap = rowResults[k];
          List rowMapNums = rowMap['nums'];
          //
          Map rowMapNum = rowMapNums[i];
          var rowCode = rowMapNum['code'];
          if (isDigit(rowCode)) {
            int digitCode = int.parse(rowCode);
            if (digitCode > maxCount) {
              maxCount = digitCode;
              // print(maxCount);
            }
          }
        }
        MaxCountArray.add({'code': maxCount.toString(), 'isRight': false});
      }
      Map digitMap = {'title': '', 'nums': MaxCountArray};
      KL_MaximumSkipping.add(digitMap);
    }
    debugPrint('KL_MaximumSkipping---$KL_MaximumSkipping');
  }

  // 使用 int.tryParse 判断字符是否为数字
  bool isDigit(String char) {
    return int.tryParse(char) != null;
  }

  ///计算最大连开
  KL_getMaximumConsecution() {
    KL_MaximumConsecution.clear();

    ///遍历每个号码分区
    for (int k = 0; k < KL_CalculatedDrawings.length; k++) {
      Map element = KL_CalculatedDrawings[k];
      List nums = element['nums'];
      List MaxCountArray = [];

      ///遍历每个分区的每一位号码
      for (int i = 0; i < nums.length; i++) {
        int maxCount = 0; //最大连开次数
        int currentCount = 0; //当前连开次数
        List isRightItems = [];

        //
        for (var j = 0; j < KL_AnalyticsRowResults.length; j++) {
          List rowResults = KL_AnalyticsRowResults[j];
          Map rowMap = rowResults[k];
          List rowMapNums = rowMap['nums'];
          Map rowMapNum = rowMapNums[i];
          bool isRight = rowMapNum['isRight'];
          isRightItems.add(isRight);
        }
        debugPrint('isRightItems---$isRightItems');
        for (bool element in isRightItems) {
          if (element) {
            currentCount++; // 如果是 '1'，则增加当前计数
          } else {
            // 如果不是 '1'，则更新最大计数并重置当前计数
            if (currentCount > maxCount) {
              maxCount = currentCount;
            }
            currentCount = 0; // 重置当前计数
          }
        }
        // 在循环结束后检查一次
        if (currentCount > maxCount) {
          maxCount = currentCount;
        }

        Map codeCountMap = {'code': maxCount.toString(), 'isRight': false};
        MaxCountArray.add(codeCountMap);
      }
      Map digitMap = {'title': '', 'nums': MaxCountArray};
      KL_MaximumConsecution.add(digitMap);
    }
    debugPrint('KL_MaximumConsecution---$KL_MaximumConsecution');
  }

  ///选号栏
  KL_getChoosingNumber() {
    KL_ChooseNumbers.clear();

    ///遍历每个号码分区
    for (int k = 0; k < KaL_Config.digitsStringArr.length; k++) {
      List digitLetters = KaL_Config.otherDigitNums;
      var codeCountArray = [];
      if (k == 0) {
        digitLetters = KaL_Config.firstDigitLetters;
      }

      ///遍历每个区的号码
      for (int i = 0; i < digitLetters.length; i++) {
        Map digitLetter = digitLetters[i];
        String codeString = digitLetter['code'];
        Map codeCountMap = {'code': codeString, 'isRight': false};
        codeCountArray.add(codeCountMap);
      }
      Map digitMap = {'title': '', 'nums': codeCountArray};
      KL_ChooseNumbers.add(digitMap);
    }
    debugPrint('KL_ChooseNumbers---$KL_ChooseNumbers');
  }
}
